package org.mmtk.plan.colormark;

import org.mmtk.plan.scale.ScaleMarkSweepSpace;
import org.mmtk.utility.Log;
import org.mmtk.utility.options.Options;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.ObjectReference;

@Uninterruptible
public final class CMSweeper extends ScaleMarkSweepSpace.Sweeper {

	/**
	 * Called for live objects in heap
	 * 
	 * always return false to signify that live objects remains live after this operation
	 */
	public boolean sweepCell(ObjectReference object) {
	  boolean result = false; 
	  
	  if (Options.verbose.getValue() >= 5) {
		  Log.write("sweepCell: enter");
		  Log.flush();
		  VM.objectModel.dumpObject(object);
	  }
	  
	  if(!VM.objectModel.validRef(object) && Options.verbose.getValue() >= 5) {
		  Log.write("sweepCell: invalid object=");
		  Log.writeln(object);
		  Log.flush();
	  }
	  
	  if(CM.cmSpace.isLive(object) && Options.verbose.getValue() >= 5) {
		  Log.write("sweepCell: marked object=");
		  Log.writeln(object);
		  Log.flush();
	  }
	  
	  ObjectReference color = VM.objectModel.getKathy(object);
	  if(color != ObjectReference.nullReference()) {	  
		  if (Options.verbose.getValue() >= 5) {
			  Log.write("sweepCell: colored object=");
			  Log.write(object);
			  Log.write(", color=");
			  Log.writeln(color);
			  Log.flush();
		  }
		  CMHelper helper = CM.getHelper(color);
		  if(helper == null) {
			  if (Options.verbose.getValue() >= 3) {
				  Log.writeln("\t !!! sweepCell, helper is null");
				  Log.flush();
				  VM.objectModel.dumpObject(object);
			  }
		  } else {
			  if(helper.isLive()) {
				  //Log.writeln("sweepCell: should be marked");
				  if(CM.cmSpace.markObject(object)) {
					  //Log.writeln("\tobject was not alive");
					  helper.addLive();
				  }
			  }
		  }
		  VM.objectModel.setKathy(object, ObjectReference.nullReference());
	  }
	  
	  if (Options.verbose.getValue() >= 5) {
		  Log.write("sweepCell: exit");
		  Log.flush();
		  VM.objectModel.dumpObject(object);
	  }
	  
	  return result;
  }
}
